<?php

namespace common\service;

use common\model\EntityModel;
use common\model\EntityRelationshipsModel;
use common\model\TaskModel;
use common\model\UserModel;
use support\SingletonTrait;
use Webman\Stomp\Client;

class EntityRelationshipService
{
    // 单例工具
    use SingletonTrait;

    /**
     * 保存实体关联关系
     * @param $entityId
     * @param $relationEntityIds
     * @return void
     * @throws \Exception
     */
    public function saveEntityRelationshipList($entityId, $relationEntityIds)
    {
        $dataKeyList = [];
        foreach ($relationEntityIds as $relationEntityId) {
            if (!is_numeric($relationEntityId)) {
                continue;
            }
            $relationEntityId = intval($relationEntityId);
            $dataKeyList[$relationEntityId] = [
                'entity_id' => $entityId,
                'relation_entity_id' => $relationEntityId,
                'uuid' => create_uuid(),
                'created' => time(),
                'created_by' => fill_created_by(),
            ];
        }

        $entityRelationshipList = model(EntityRelationshipsModel::class)->where(['entity_id' => $entityId])->select();

        $entityRelationshipKeyList = [];
        foreach ($entityRelationshipList as $entityRelationshipItem) {
            $entityRelationshipKeyList[$entityRelationshipItem['relation_entity_id']] = $entityRelationshipItem;
        }

        $addData = array_diff_key($dataKeyList, $entityRelationshipKeyList);
        $deleteData = array_diff_key($entityRelationshipKeyList, $dataKeyList);
        //添加实体关联关系
        if (!empty($addData)) {
            model(EntityRelationshipsModel::class)->addAll(array_values($addData));
        }

        //同步任务上游关系 --- 删除之前  新增之后
        $this->syncTaskUpstreamByEntityId($entityId);

        //删除关联关系
        if (!empty($deleteData)) {
            $deleteIds = array_column($deleteData, 'id');
            model(EntityRelationshipsModel::class)->deleteItem(['id' => ["IN", $deleteIds]]);
        }

    }

    /**
     * 同步任务上下游关系--通过实体ID
     * @param int $entityId 实体ID
     * @return void
     */
    public function syncTaskUpstreamByEntityId(int $entityId)
    {
        if (empty($entityId)) {
            return;
        }

        //关联实体--同步任务上游
        $closedStatus = StatusService::getInstance()->getTaskDefaultClosedStatus();
        $taskIds = model(TaskModel::class)
            ->where(['entity_id' => $entityId])
            ->where(["json->>'$.task_status'" => ['NEQ', $closedStatus['id']], 'step_type' => TaskModel::STEP_TYPE_STEP])
            ->field('id')
            ->column('id');

        Client::send('task_upstream', build_queue_data_with_xu(['task_ids' => $taskIds ]) );
    }


    /**
     * 获取实体关系
     * @param $entityId
     * @return array
     */
    public function getEntityRelationshipInfo($entityId)
    {
        $entity = model(EntityModel::class)
            ->field("id,project_id,name,initial_episode_code,showings_number,code,module_id,json,JSON_UNQUOTE(JSON_EXTRACT(`json`,'$.design_category'))")
            ->find($entityId);

        if (empty($entity)) {
            return [];
        }

        if (in_array(module_by_id($entity['module_id'])['code'], ['design', 'storyboard'])) {
            //如果是概念或者 则再获取children entity
            $childrenEntity = EntityService::getInstance()->getDownstreamEntity($entity);
            if (empty($childrenEntity)) {
                return [];
            }
            $entity = $childrenEntity;
        }


        $moduleCode = module_by_id($entity['module_id'])['code'];

        // $moduleCode 在 level , shot 内 则用entity_id查询 否则用relation_entity_id
        if (in_array($moduleCode, ['level', 'shot'])) {
            $filter = [
                'entity_id' => $entity['id'],
            ];
        } else {
            $filter = [
                'relation_entity_id' => $entity['id'],
            ];
        }

        $entityRelationshipsList = model(EntityRelationshipsModel::class)->where($filter)->select();

        if (empty($entityRelationshipsList)) {
            return [];
        }

        $userList = model(UserModel::class)->where(['id' => ['IN', array_column($entityRelationshipsList, 'created_by')]])->field("id,name")->select();
        $userList = array_column($userList, null, 'id');

        foreach ($entityRelationshipsList as $entityRelationshipsIndex => $entityRelationshipsItem) {
            $entityRelationshipsItem['created_by'] = $userList[$entityRelationshipsItem['created_by']] ?? [];
            $entityRelationshipsList[$entityRelationshipsIndex] = $entityRelationshipsItem;
        }

        return in_array($moduleCode, ['level', 'shot']) ? array_column($entityRelationshipsList, null, 'relation_entity_id') : array_column($entityRelationshipsList, null, 'entity_id');
    }


    /**
     * 获取上游实体关系
     * @param $entityId
     * @return array
     */
    public function getUpEntityRelationshipInfo($entityId)
    {
        $shipMap = $this->getEntityRelationshipInfo($entityId);

        if (empty($shipMap)) {
            return [];
        }

        //替换key 为 design , storyboard
        $entityIds = array_keys($shipMap);

        $entityList = model(EntityModel::class)
            ->join("module on module.id = entity.module_id")
            ->where(["entity.id" => ["IN", $entityIds]])
            ->field(["entity.id", "entity.module_id",
                    "JSON_UNQUOTE(JSON_EXTRACT(entity.json, CONCAT('$.',module.code,'_design'))) as design_id",
                    "JSON_UNQUOTE(JSON_EXTRACT(entity.json, CONCAT('$.shot_storyboard'))) as storyboard_id",
                ]
            )->select();

        $entityList = array_column($entityList, null, 'id');

        $result = [];
        foreach ($shipMap as $shipMapIndex => $shipMapItem) {
            if (isset($entityList[$shipMapIndex])) {
                if (!empty($entityList[$shipMapIndex]['design_id'])) {
                    $result[$entityList[$shipMapIndex]['design_id']] = $shipMapItem;
                }
                if (!empty($entityList[$shipMapIndex]['storyboard_id'])) {
                    $result[$entityList[$shipMapIndex]['storyboard_id']] = $shipMapItem;
                }
            }
        }
        return $result;
    }

    public function saveDesignRelations($designIdList)
    {
    }
}
